<template>
    <el-table  ref="multipleTable"  v-loading="listLoading"
        border   stripe
        style="width: 100%;margin-bottom: 20px;"
        :row-key="rowKey"
        @select="rowSelect"
        @select-all="selectAll"
        :data="data"
        :default-expand-all = "expandAll"
        :tree-props="{children: 'children' }">

        <el-table-column  type="selection" width="55"  align="center">
        </el-table-column>

        <el-table-column v-for="column in columns"   :key="column.value" :label="column.text" :width="column.width"  :align="column.align ? column.align: 'center'">
            <template slot-scope="scope">

                <!-- 行内显示图片 -->
                <img   v-if="column.imgFlag==true"   :src="CMBASE.baseFileContext + scope.row[column.value]" width="60" height="60"  class="img"/>

                <i   v-else-if="column.iconFlag==true" :class="scope.row[column.value]"></i>

                <!-- 行内格式自定义 -->
                <span v-else-if="column.formatter"> {{column.formatter(scope.row)}}</span>

                <!-- 行内显示tag标签 -->
                <span  v-else-if="column.tagFlag==true">
                    <span v-for="item in column.tagFormatter" :key="item.value" >
                    <el-tag v-if="item.value==scope.row[column.value]"   :type="item.type">{{item.text}}</el-tag>
                    </span>
                </span>

                <!-- 行内显示开关按钮 -->
                <el-switch  v-else-if="column.switchFlag==true"  v-model="scope.row[column.value]"  disabled
                    :active-value="1"  :inactive-value="0"   @change =  "(value) => column.changeEvent(value,scope.row)"  >
                </el-switch>
                <!-- 行内显示下拉列 -->
                <el-select  v-else-if="column.selectFlag==true"  v-model="scope.row[column.value]" >
                    <el-option v-for="item in column.dataSource" :key="item.value"
                        :label="item.text" :value="item.value">
                    </el-option>
                </el-select>
                <!-- 行内显示文本内容（默认） -->
                <span v-else>{{scope.row[column.value]}}</span>



            </template>
        </el-table-column>
        <slot/>
    </el-table>
</template>

<script>
/**
  Auth: Lei.j1ang
  Created: 2018/1/19-13:59
*/
import   translateTreeToData  from './eval2'
export default {
    name: 'TreeTable',
    props: {
        /* eslint-disable */
        data: {
            type: [Array, Object],
            required: true
        },
        columns: {
            type: Array,
            default: () => []
        },
        evalFunc: Function,
        evalArgs: Array,
        expandAll: {
            type: Boolean,
            default: false
        },
        rowKey: {
            type: String,
            default: "id"
        },
        listLoading: {
            type: Boolean,
            default: true
        }
    },
    watch:{

    },
    data() {
        return {
            originalData: [], //后台返回的原始数据
        }
    },
    created(){

        this.originalData = translateTreeToData( this.data );

    },
    computed: {
        // 格式化数据源
        // formatData: function() {
        //   let tmp
        //   if (!Array.isArray(this.data)) {
        //     tmp = [this.data]
        //   } else {
        //     tmp = this.data
        //   }
        //   const func = this.evalFunc || treeToArray
        //   const args = this.evalArgs ? Array.concat([tmp, this.expandAll], this.evalArgs) : [tmp, this.expandAll]
        //   return func.apply(null, args)
        // }
    },
    methods: {

        showCheckedStatus( ids ){
            this.selectByRecursion2( this.$refs.multipleTable.data , ids );
        },

        /**
         * 递归修改子节点状态
         * @param children 递归数据
         * @param status 选中数据
         */
        selectByRecursion2( children, data) {

            for (let index = 0; index < children.length; index++) {
                const element = children[index];
                let flag = this.getFlag(  element.id , data ) ;

                this.$refs.multipleTable.toggleRowSelection( element, flag !=null )
                element.isChecked =  flag !=null
                if( flag !=null ){
                    element.dataPerm = parseInt(flag.dataPerm);
                }
                if( element.children ){
                    this.selectByRecursion2(element.children , data)
                }
            }
        },

        getFlag( id , data ){
            for (let index = 0; index < data.length; index++) {
                const element = data[index];
                if( element.menuId ===id  ){
                    return element
                }
            }
            return null ;
        },


        rowSelect(selection, row) {
            //递归修改子节的状态
            this.selectByRecursion(row, !row.isChecked)
            //检测是否需要修改父节点状态
            this.isCheckParent(selection, row)
        },
        //全选
        selectAll(selection) {
            //获取selection中一级菜单的数量，与全部一级数量对比，获取当前是 全部选择 or 全部取消
            let firstMenu = selection.filter((item) => item.pid === '' )
            this.$refs.multipleTable.data.map((items) => {
                this.selectByRecursion(
                    items,
                    firstMenu.length === this.data.length
                )
            })
        },
        /**
         * 递归修改子节点状态
         * @param startItem 当前节点
         * @param status 状态
         */
        selectByRecursion(startItem, status) {
            //修改当前节点状态
            this.$refs.multipleTable.toggleRowSelection(startItem, status)
            startItem.isChecked = status
            if (startItem.children) {
                startItem.children.forEach((item) =>
                    this.selectByRecursion(item, status)
                )
            }
        },
        /**
         * 检测是否需要修改父节点状态
         * @param selection 所有已选项
         * @param row 当前节点
         */
        isCheckParent(selection, row) {
            if (row.pid === '') return
            //获取当前节点 的 父节点包含的 所有字节点
            let allChild = this.originalData.filter(
                (item) => item.pid === row.pid
            )
            //获取当前节点 的 父节点包含的 所有字节点  中 已选中的节点
            let selectChild = selection.filter(
                (item) => item.pid === row.pid
            )
            //查找父节点
            let parentItem = this.getParentItem(
                this.$refs.multipleTable.data,
                row.pid
            )

            //如果当前为选中状态，判断父节点是否需要选中
            if (row.isChecked) {

                parentItem.isChecked = true
                this.$refs.multipleTable.toggleRowSelection(parentItem, true)

                // if (selectChild.length === allChild.length) {
                //     this.$refs.multipleTable.toggleRowSelection(parentItem, true)
                //     parentItem.isChecked = true
                // }else{
                //     parentItem.isChecked = false
                // }
            } else {

                if (selectChild.length === 0 ) {

                    this.$refs.multipleTable.toggleRowSelection(parentItem, false)
                    parentItem.isChecked = false
                }

                //如果当前为未选中状态，判断父节点是否需要取消选中
                // if (selectChild.length !== allChild.length) {
                //     this.$refs.multipleTable.toggleRowSelection(parentItem, false)
                //     parentItem.isChecked = false
                // }else{
                //     parentItem.isChecked = true
                // }
            }
        },
        /**
         * 递归查找父节点 （效率一般，可以更改查找模式）
         * @param list 循环列表
         * @param pId 查找的父节点id
         * @param pItem 查找到的值
         * @returns {null}
         */
        getParentItem(list, pId, pItem = null) {
            list.some((item) => {
                if (item.id === pId) {
                    pItem = item
                    return true
                } else if (item.children && item.children.length > 0) {
                    pItem = this.getParentItem(item.children, pId, pItem)
                    return !!pItem
                } else {
                    return false
                }
            })
            return pItem
        },





        forArr(arr, isExpand) {
            arr.forEach(i => {
                this.$refs.theTable.toggleRowExpansion(i, isExpand)
                if (i.children) {
                    this.forArr(i.children, isExpand)
                }
            })
        },
        expandAllRow() { // 默认展开全部的话，首次加载需要在$nextTick下进行
            this.forArr(this.data, true)
        },
        collapseAllRow() {
            this.forArr(this.data, false)
        },

        // 图标显示
        iconShow(index, record) {
            return (index === 0 && record.children && record.children.length > 0)
        }
    }
}
</script>
<style rel="stylesheet/css">
    @keyframes treeTableShow {
        from {opacity: 0;}
        to {opacity: 1;}
    }
    @-webkit-keyframes treeTableShow {
        from {opacity: 0;}
        to {opacity: 1;}
    }
</style>

<style lang="scss" rel="stylesheet/scss" scoped>
    $color-blue: #2196F3;
    $space-width: 18px;
    .ms-tree-space {
        position: relative;
        top: 1px;
        display: inline-block;
        font-style: normal;
        font-weight: 400;
        line-height: 1;
        width: $space-width;
        height: 14px;
        &::before {
        content: ""
        }
    }
    .processContainer{
        width: 100%;
        height: 100%;
    }
    table td {
        line-height: 26px;
    }

    .tree-ctrl{
        position: relative;
        cursor: pointer;
        color: $color-blue;
        margin-left: -$space-width;
    }
</style>
